package com;
/*
* 面向对象之--- 继承
* 子类对父类进行扩展，从一般到特殊的关系，父类放共性，子类放特性
* 作用：
*   - 描述一个体系，解决代码重复
* 注意：
*   - 类只允许单继承，不允许多继承，支持多重继承
*   - java.lang.Object 类是Java的根类，任何类都是Object类的子类/间接子类
*
* 子类可以访问父类的成员，   public & protected 修饰，同包中缺省访问权限修饰符的成员
*                        private 是不能直接访问的，   不同包中缺省访问权限修饰符的成员
* super关键字： 调用子类构造器之前一定会调用父类中可以被子类访问的构造器，完成父类字段初始化操作，隐式调用父类无参数构造器 super();（从该类所在继承树最顶层类的构造器开始执行）
*   - 若父类没有可以被子类访问的无参构造器，那么子类就必须显示通过 super 语句调用父类带参的构造器
*   - 在子类的构造方法中调用父类指定的构造器  super(name,age); （必须作为构造方法中的第一条语句）
*   - 在子类中访问父类的被隐藏的实例变量或调用父类的覆盖的实例方法 super.name super.fly();
*
* 方法覆盖 Override: 解决子类继承父类之后，可能父类的另一个方法不满足子类的具体特征，此时需要重新在子类定义该方法，并重写方法体
*   - 一同： 实例方法签名必须相同
*   - 两小：
*       子类方法的返回值类型和父类方法的返回类型相同或者是其子类
*       子类方法声明抛出的异常类和父类方法声明抛出的异常相同或者子类是其子类（运行时异常除外）
*           子类方法中声明抛出的异常小于或等于父类方法中声明抛出异常类
*           子类方法可以同时声明抛出多个属于父类方法声明抛出异常的子类（子类也可以不声明抛出）
*   - 一大：子类方法的访问权限比父类方法访问权限更大或者相等（防止父类方法失传）
*
* @Override标签
*
* */

class SuperClass{
    public String name = "alex";
    public static void ooxx(){

    }

    public static void item(){
        System.out.println("This is SuperClass item method");
    }

    public void make_sound(){
        System.out.println("this is superclass");
    }
}

// 重写父类方法-  直接拷贝父类方法的定义，修改方法体
// 只有非 private、final 修饰的实例方法才有覆盖的概念
// 隐藏： 父类类方法、父类字段（字段名相同，不管类型）、 本类字段（局部变量）

class SubClass extends SuperClass{
    public int name = 151;   // 隐藏了 父类 name  字段

    public void doWork(){
        boolean name = false;//  隐藏了本类中的  name 变量
        System.out.println(name);  //  false
        System.out.println(this.name); // 151
        System.out.println(super.name);//  alex
    }

    // 隐藏， 不是方法覆盖
    public static void ooxx(){

    }

    // 隐藏 父类方法 ， 不是方法覆盖
    public static void item(){
        System.out.println("This is SubClass item method");
    }

    // 方法重写
    @Override
    public void make_sound(){
        System.out.println("this is subclass");
    }

}

// 组合  Composite
class OldClass{
    public void method(){
        System.out.println("这里是旧类的逻辑代码......");
    }
}

class NewClass{
    public OldClass obj = new OldClass();
    public void method(){
        obj.method();
        System.out.println("在新类中添加自己的逻辑代码......");
    }

    // 重载 overload 是在同一个类中定义 对个同名的方法， 但这些方法的参数类型或数量必须不同。

    // 重载add method
    public int add(int a , int b){
        return a + b;
    }

//    public float add(float a , float b){
//        return a + b;
//    }

    public double add(double a , double b){
        return a + b;
    }

    public int add(int a ,int b, int c){
        return a + b + c;
    }

}


public class Inheritance {
    public static void main(String[] args) {

        SubClass sub = new SubClass();
        sub.doWork();
        sub.item();

        // 方法重写
        sub.make_sound();


        // Composite
        NewClass new_obj = new NewClass();
        new_obj.method();

        // 重载方法
        // 调用 int add
        System.out.println("Sum of 2 integers: " + new_obj.add(145,125));

        // 调用 int double
        System.out.println("Sum of 2 double: " + new_obj.add(145.1,125.5));

        // 调用 int add(a,b,c)
        System.out.println("Sum of 3 integers: " + new_obj.add(145,125 , 646));


    }
}
